import base64
import hashlib

import pymongo
import redis
import requests
import execjs
import json
# pip install retrying
from retrying import retry


class Construct:
    def __init__(self):
        self.redis_conn = redis.Redis(host='192.168.80.3', port=6379, db=1)
        self.mongo_client = pymongo.MongoClient(host='175.178.162.117', port=27017, username="root",
                                                password="H5rOx4dG")
        self.collection = self.mongo_client['py_spider']['yn_construct']
        self.redis_set_key = 'yn_construct_unique_set'

        self.headers = {
            "Accept": "application/json, text/plain, */*",
            "Accept-Language": "zh-CN,zh;q=0.9",
            "Cache-Control": "no-cache",
            "Connection": "keep-alive",
            "Content-Type": "application/json;charset=UTF-8",
            "Origin": "https://www.ynjzjgcx.com",
            "Pragma": "no-cache",
            "Referer": "https://www.ynjzjgcx.com/dataPub/enterprise",
            "Sec-Fetch-Dest": "empty",
            "Sec-Fetch-Mode": "cors",
            "Sec-Fetch-Site": "same-origin",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
            "appId": "84ded2cd478642b2",
            "isToken": "false",
            "sec-ch-ua": '"Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"',
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-platform": '"Windows"'
        }

        with open("云南建设.js", encoding="utf-8") as f:
            self.js_code = f.read()

    def slide_verify(self, slide_image, background_image, verify_type="20111"):
        # 滑块类型
        # 通用双图滑块  20111
        payload = {
            "slide_image": slide_image,
            "background_image": background_image,
            "token": "7pE3vAgqNa3cDZ4iQULCogDd6oupapu9BVOLI9Fj32U",
            "type": verify_type
        }
        resp = requests.post("http://api.jfbym.com/api/YmServer/customApi",
                             headers={'Content-Type': 'application/json'},
                             data=json.dumps(payload))
        print(resp.text)
        return resp.json()['data']['data']

    def get_code(self):
        url = "https://www.ynjzjgcx.com/prod-api/mohurd-pub/vcode/genVcode"
        params = execjs.compile(self.js_code).call("encrypt_params", {"key": "query"})

        response = requests.post(url, headers=self.headers, json={'params': params})
        res = response.json()

        small_image = json.loads(res['data'])['smallImage']
        big_image = json.loads(res['data'])['bigImage']
        slide_id = json.loads(res['data'])['slideId']

        with open('smallImage.png', 'wb') as f:
            f.write(base64.b64decode(small_image))
        with open('bigImage.png', 'wb') as f:
            f.write(base64.b64decode(big_image))

        width = self.slide_verify(small_image, big_image)
        return slide_id, width

    @retry(wait_random_min=1000, wait_random_max=5000, stop_max_attempt_number=5)
    def get_data(self, page_num):
        # 获取验证码
        slide_id, width = self.get_code()
        param = {
            "pageNum": page_num,
            "pageSize": 10,
            "certificateType": "",
            "name": "",
            "key": "query",
            "slideId": slide_id,
            "width": width
        }
        params = execjs.compile(self.js_code).call("encrypt_params", param)
        # 采集数据
        url = "https://www.ynjzjgcx.com/prod-api/mohurd-pub/dataServ/findBaseEntDpPage"
        response = requests.post(url, headers=self.headers, json={'params': params})
        result = response.json()
        if result['code'] == 200:
            for data in result['data']['records']:
                item = dict()
                item['company_name'] = data['name']
                item['credit_code'] = data['creditCode']
                item['address'] = data['address']

                md5 = hashlib.md5(data['name'].encode()).hexdigest()
                # redis去重，不存在才入库
                if self.redis_conn.sadd(self.redis_set_key, md5) != 0:
                    self.collection.insert_one(item)
                    print("入库成功：", item)
        else:
            print(result)
            raise requests.exceptions.ReadTimeout('数据获取出错')


if __name__ == '__main__':
    c = Construct()
    for page in range(11):
        c.get_data(page)
